package auctionatr

import grails.plugin.mail.MailService

/**
 * Diese Klasse ist der entsprechende Controller zur Model-class Bid. Alle Methoden, die in Verbindung mit einem Gebot stehen, werden u.a. in dieser Klasse gesteuert.
 * 
 * @author Can Paul
 *
 */
class BidController extends BaseController {

	/**
	 * Initiate E-Mail Service
	 */
	SendEmailService sendEmailService

	/**
	 * erlaubte Zugriffsmethoden
	 */
	static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

	/**
	 * Der User wird automatisch auf die Liste aller Gebote weitergeleitet.
	 */
	def index = {
		redirect(action: "list", params: params)
	}

	// Funktion nicht existent
	//	def list = {
	//		params.max = Math.min(params.max ? params.int('max') : 10, 100)
	//		[bidInstanceList: Bid.list(params), bidInstanceTotal: Bid.count()]
	//	}

	/**
	 * Seite zur Abgabe eines neuen Gebots.
	 */
	def create = {
		def bidInstance = new Bid()
		bidInstance.properties = params
		def auctionInstance = Auction.get(params.id ? params?.id : params?.auctions?.id)
		def lastBid = Bid.findByAuctions(auctionInstance, [max: 1, order: 'desc', sort: 'gebot'])?.gebot
		if(lastBid == null) {
			lastBid = auctionInstance.startPrice
		}
		def nextBid = lastBid+grailsApplication.config.nextBid

		// in save nachziehen
		return [bidInstance: bidInstance, nextBid : nextBid]
	}

	/**
	 * Beim Klick auf "Anlegen" wird das Gebot für die entsprechende Auktion angelegt. 
	 * Nach erfolgreicher Abgabe des Gebots gelangt der User zur Auktionsansicht, auf die er geboten hat, und es erscheint eine Bestätigungsbenachrichtigung, dass das Gebot erfolgreich abgegeben wurde. Wenn ein Gebot nicht erfolgreich abgegeben werden konnte (z.B. weil die Bedingungen zur Gebotsabgabe nicht erfüllt wurden), erscheint eine Fehlermeldung und der User bleibt auf der Gebotsabgabeseite der entsprechenden Auktion.
	 */
	def save = {
		// neues Gebot initiieren:
		def bidInstance = new Bid(params)
		// Auktionsdaten auslesen
		def auc = Auction.findById(bidInstance.properties['auctions'].id)

		// letztes Bid für eventuelle Fehlermeldungen auslesen:
		def lastBidData = Bid.findByAuctions(auc, [max: 1, order: 'desc', sort: 'gebot'])
		def lastBid = 0
		// letztes Gebot bestimmen
		if(lastBidData == null) {
			lastBid = auc.startPrice
		} else {
			lastBid = lastBidData.gebot
		}
		// Mindestgebot bestimmen:
		def nextBid = lastBid+grailsApplication.config.nextBid

		// falls Verkäufer=Bieter oder Auktion bereits beendet, Fehler:
		if(session?.userid == auc['users'].id || auc['finishDate'] < new Date()) {
			bidInstance.errors.rejectValue("users","default.accessdenied.message")
			render(view: "create", model: [bidInstance: bidInstance, nextBid : nextBid])
		} else { // sonst Speichervorgang einleiten

			// dem Gebot den User zuweisen
			def userInstance = User.get(session?.userid)
			bidInstance.properties['users'] = userInstance

			// Wenn nicht erstes Gebot, Mailversand, dass Überbietung stattgefunden hat:
			if(lastBidData != null) {
				sendEmailService.sendEmailWhenNotHighestBidderAnymore([email: lastBidData.users.email, auction: auc['name'], name: lastBidData.users.username, bid: params?.gebot, bidder: userInstance.username])
			}

			
			if (bidInstance.save(flush: true)) {

				// Erfolgsnachricht:
				flash.message = "${message(code: 'bid.created.message')}"
				// nach erfolgreichem Gebot zur Auktion weiterleiten:
				redirect(controller: 'auction', action: "show", id: bidInstance.properties['auctions'].id)
			}
			else {
				render(view: "create", model: [bidInstance: bidInstance, nextBid : nextBid])
			}
		}
	}

	/*	* Von Grails automatisch generiert. Hiermit könnte ein Gebot inkl. Löschungslink angezeigt werden.
	 * Diese Methode wird derzeit nicht genutzt!
	 
	def show = {
		def bidInstance = Bid.get(params.id)
		if (!bidInstance) {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'bid.label', default: 'Bid'), params.id])}"
			redirect(action: "list")
		}
		else {
			[bidInstance: bidInstance]
		}
	}
	*/

	//	def edit = {
	//		def bidInstance = Bid.get(params.id)
	//		if (!bidInstance) {
	//			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'bid.label', default: 'Bid'), params.id])}"
	//			redirect(action: "list")
	//		}
	//		else {
	//			return [bidInstance: bidInstance]
	//		}
	//	}
	//
	//	def update = {
	//		def bidInstance = Bid.get(params.id)
	//		if (bidInstance) {
	//			if (params.version) {
	//				def version = params.version.toLong()
	//				if (bidInstance.version > version) {
	//
	//					bidInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [
	//						message(code: 'bid.label', default: 'Bid')]
	//					as Object[], "Another user has updated this Bid while you were editing")
	//					render(view: "edit", model: [bidInstance: bidInstance])
	//					return
	//				}
	//			}
	//			bidInstance.properties = params
	//			if (!bidInstance.hasErrors() && bidInstance.save(flush: true)) {
	//				flash.message = "${message(code: 'default.updated.message', args: [message(code: 'bid.label', default: 'Bid'), bidInstance.id])}"
	//				redirect(action: "show", id: bidInstance.id)
	//			}
	//			else {
	//				render(view: "edit", model: [bidInstance: bidInstance])
	//			}
	//		}
	//		else {
	//			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'bid.label', default: 'Bid'), params.id])}"
	//			redirect(action: "list")
	//		}
	//	}

// von Grails automatisch generiert. Hiermit könnte die Löschung eines Gebots implementiert werden.
/*	/**
	 * Durch diese Methode kann ein Gebot gelöscht werden, allerdings kann eine Gebotslöschung nur durch einen Administrator erfolgen. 
	 *	/
	def delete = {
		if(session?.admin == true) {
			def bidInstance = Bid.get(params.id)
			// Wenn Gebot gefunden:
			if (bidInstance) {
				try {
					bidInstance.delete(flush: true)
					flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'bid.label', default: 'Bid'), params.id])}"
					redirect(controller: "auction", action: "list")
				}
				catch (org.springframework.dao.DataIntegrityViolationException e) {
					flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'bid.label', default: 'Bid'), params.id])}"
					redirect(action: "show", id: params.id)
				}
			}
			else { // falls Gebot nicht gefunden:
				flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'bid.label', default: 'Bid'), params.id])}"
				redirect(controller: "auction", action: "list")
			}
		} else { //falls nicht Admin
			redirect(controller: 'portal', view: 'index')
		}
	}
*/
	
	/**
	 * 	Vor dem Aufruf einer Seite muss überprüft werden, ob ein User eingeloggt ist. Mit dieser Methode wird festgelegt, für welche Seiten eine Authentifizierung nicht notwendig ist.
	 */
	def beforeInterceptor = [action:this.&auth,except:['show',]]

}
